package com.wft.design.upms.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wft.design.common.mybatis.service.impl.BaseServiceImpl;
import com.wft.design.upms.channel.SysMenuChannel;
import com.wft.design.upms.entity.SysMenu;
import com.wft.design.upms.mapper.SysMenuMapper;
import com.wft.design.upms.service.SysMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

/**
 * @author WFT
 * @date 2020/2/7
 * description:
 */
@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    private final SysMenuChannel menuChannel;

    @Override
    public List<SysMenu> selectList() {
        return this.list();
    }

    @Override
    public SysMenu selectById(Long menuId) {
        return this.getById(menuId);
    }

    /**
     * 根据唯一标识获取菜单信息
     * @param permission java.lang.String
     * @return com.wft.design.upms.entity.SysMenu
     */
    private SysMenu selectByPermission(String permission){
        return this.getOne(Wrappers.<SysMenu>lambdaQuery().eq(SysMenu::getPermission,permission));
    }

    @Override
    public void createMenu(SysMenu menu) {
        Assert.isNull(this.selectByPermission(menu.getPermission()),"唯一标识已存在");
        //  默认为最大值
        if (null == menu.getSort()){
            menu.setSort(Integer.MAX_VALUE);
        }
        //  设置创建时间与修改时间
        LocalDateTime now = LocalDateTime.now();
        menu.setCreateTime(now);
        menu.setLastModifyTime(now);
        //  保存菜单
        if (this.save(menu)){
            //  异步将此菜单的访问操作权限授权于最大角色,并重新设置排序值字段
            Message<SysMenu> message = MessageBuilder.withPayload(menu)
                    .setHeader("method","add")
                    .build();
            this.menuChannel.output().send(message);
        }
    }

    @Override
    public void updateMenu(SysMenu menu) {
        //  获取原菜单信息
        SysMenu dbMenu = this.selectById(menu.getId());
        Assert.notNull(dbMenu,"Id不存在");
        //  判断是否修改了唯一标识
        if (!dbMenu.getPermission().equals(menu.getPermission())){
            Assert.isNull(this.selectByPermission(menu.getPermission()),"唯一标识已存在");
        }
        //  设置创建时间与最后修改时间
        menu.setCreateTime(dbMenu.getCreateTime());
        menu.setLastModifyTime(LocalDateTime.now());
        //  默认为最大值
        if (null == menu.getSort()){
            menu.setSort(Integer.MAX_VALUE);
        }
        //  保存
        if (this.updateById(menu)){
            //  判断是否需要重新设置排序值字段
            if (dbMenu.getSort().equals(menu.getSort())){
                //  重新设置排序值字段
                Message<SysMenu> message = MessageBuilder.withPayload(menu)
                        .setHeader("method","edit")
                        .build();
                this.menuChannel.output().send(message);
            }
        }
    }

    @Override
    public void deleteMenuById(Long menuId) {
        //  获取需要删除的菜单信息
        SysMenu dbMenu = this.selectById(menuId);
        Assert.notNull(dbMenu,"Id不存在");
        //  删除菜单
        if (this.removeById(menuId)){
            //  异步删除此菜单与角色间的绑定关系,并重新设置同级菜单的排序值和删除此菜单下的子菜单
            Message<SysMenu> message = MessageBuilder.withPayload(dbMenu)
                    .setHeader("method","del")
                    .build();
            this.menuChannel.output().send(message);
        }
    }

    @Override
    public List<SysMenu> selectMenuListByPid(Long pid, Collection<String> authorities) {
        LambdaQueryWrapper<SysMenu> wrapper = Wrappers.<SysMenu>lambdaQuery()
                //  只查询菜单
                .eq(SysMenu::getType,1)
                //  匹配权限
                .in(SysMenu::getPermission,authorities);
        if (null == pid || 0 == pid) {
            //  查询顶级菜单
            wrapper.eq(SysMenu::getPid,0);
        } else {
            //  过滤父级菜单
            wrapper.notIn(SysMenu::getId,pid);
            //  查询某节点下的所有子节点
            SysMenu parentMenu = this.selectById(pid);
            wrapper.likeRight(SysMenu::getIndexes,parentMenu.getIndexes());
        }
        return this.list(wrapper);
    }
}
